package com.talkyun.openx.utils;

import com.talkyun.utils.helper.RegxHelper;
import com.talkyun.utils.json.JSON;

import java.lang.reflect.Array;
import java.util.Map;

import static com.talkyun.utils.Reflector.getValue;
import static com.talkyun.utils.helper.RegxHelper.getInclude;

public class OGNL {

    public static final String ARRAY_REGX = "\\[\\d{1,}\\]";

    // path = a.b.c[0].d
    public static Object findAsJsonPath(Object obj, String path) {
        if (obj == null || path == null) {
            return null;
        }

        Object ctx = obj;
        Object val = null;

        String[] properties = path.trim().split("\\.");
        for (String property : properties) {
            property = property.trim();

            // string to map
            if (ctx instanceof String) {
                ctx = JSON.toJavaObject((String) ctx, Map.class);
            }

            if (RegxHelper.isInclude(property, ARRAY_REGX)) {
                // 1 -> array property: property[x], reg:\[\d{1,}\]
                val = getArrayItemValue(ctx, property);
            } else if (ctx instanceof Map) {
                // 2 -> val is map
                val = ((Map) ctx).get(property);
            } else {
                // 3 -> simple property
                val = getValue(ctx, property);
            }

            // last -> ready next loop
            if (val == null) {
                break;
            }
            ctx = val;
        }

        return val;
    }

    private static Object getArrayItemValue(Object ctx, String property) {
        String realProperty = RegxHelper.getHeadOther(property, ARRAY_REGX);
        int arrayNo = Integer.parseInt(getInclude(getInclude(property, ARRAY_REGX), "\\d{1,}"));
        Object val = getValue(ctx, realProperty);
        return val == null ? null : Array.get(val, arrayNo);
    }
}